﻿using ldhWebApiIIS.Extens;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.Mvc.Filters;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Security.Principal;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ldhWebApiIIS.filters
{
    public class BasicAuthenticationFilterAttribute : AuthorizationFilterAttribute
    {
        public override Task OnAuthorizationAsync(AuthorizationContext context)
        {
            var http = context.HttpContext.Request.HttpContext;
            var identity = ParseAuthorizationHeader(http);
            if (identity == null)
            {
                base.Fail(context);
                return Task.Run(() => { Challenge(http); });
            }
            if (!OnAuthorizeUser(identity.Name, identity.Password))
            {
                base.Fail(context);
                return Task.Run(() => { Challenge(http); });
            }
            var principal = new GenericPrincipal(identity, null);
            Thread.CurrentPrincipal = principal;
            return base.OnAuthorizationAsync(context);
        }

        protected virtual bool OnAuthorizeUser(string username, string password)
        {
            if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password)) { return false; }

            if (username != password)
                return false;

            return true;
        }

        protected virtual BasicAuthenticationIdentity ParseAuthorizationHeader(HttpContext actionContext)
        {
            var authHeader = actionContext.Request.Headers["Authorization"].FirstOrDefault();
            if (string.IsNullOrEmpty(authHeader))
                return null;

            if (authHeader.StartsWith("Basic"))
                authHeader = authHeader.Split(' ')[1];

            //判断是否Rsa加密
            var authHeader1 = RsaComputer.GetComputer().Decode(authHeader);
            if (authHeader1 == string.Empty)
            {
                //如果不是即使用基础的basic64
                var result = Extens.Base64.IsBase64String(authHeader);
                if (result.result)
                {
                    authHeader = result.content;
                }
                else
                {
                    return null;
                }
            }
            var tokens = authHeader.Split(':');
            if (tokens.Length < 2)
                return null;

            return new BasicAuthenticationIdentity(tokens[0], tokens[1]);
        }

        void Challenge(HttpContext actionContext)
        {
            actionContext.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
            actionContext.Response.Headers.Add("WWW-Authenticate", string.Format("Basic realm=\"{0}\"", actionContext.Request.Host));
        }
    }

    public class BasicAuthenticationIdentity : GenericIdentity
    {
        public BasicAuthenticationIdentity(string name, string password) : base(name, "Basic")
        {
            this.Password = password;
        }

        /// <summary>
        /// Basic Auth Password for custom authentication
        /// </summary>
        public string Password { get; set; }
    }
}
